home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 016a / love4th.zip / ASM&LINK.DOC < prev    next >
Text File  |  1991-10-01  |  18KB  |  396 lines

  1.                 Third Party Assembler Interface and Linker
  2.  
  3.         Traditionally in Forth systems, a "Forth Assembler" has been
  4. included.  Adding assembler components to high level language can
  5. produce dramatic improvements in performance and capability over high
  6. level Forth.   Unfortunately these assemblers are usually written in
  7. Forth, and have serious limitations.  Often the syntax is markedly
  8. different from the expected syntax for the particular processor.  It is
  9. usually difficult enough for most programmers to work in normal
  10. assembler syntax, without having to learn a new one.
  11.  
  12.         L.O.V.E. FORTH has been designed to use virtually any third
  13. party assembler, using standard assembler syntax.  Whenever CODE ,
  14. ;CODE or ASM is encountered, Forth calls in the third party assembler
  15. to process the word, and links in the resulting object file, with a
  16. built-in linker.  This means that not only can normal syntax be used in
  17. words created by the programmer, but that assembly language program
  18. sections from other sources can be included with little or no
  19. modification.
  20.  
  21.         The authors recommend the excellent assember A86 by Isaacson,
  22. also available as shareware.  The original L.O.V.E. FORTH RPN assembler 
  23. is included with the system as source code, to be used if desired.
  24.  
  25.         Operation
  26.  
  27.         A small amount of set-up is required in order to configure the
  28. system.   The authors have already included configuration files for
  29. A86, Microsoft's MASM and Borland's TASM (see Assember Set-up below).
  30. For simple code words, like those supported by the old RPN assemblers,
  31. use is straight forward.  For example, a word to make four copies of
  32. the top of stack:
  33.  
  34.         CODE DUP4 ; ( n -- n,n,n,n )
  35.                 pop ax
  36.                 push ax  ; push some copies
  37.                 push ax
  38.                 push ax
  39.                 push ax
  40.                 next c;
  41.         The operation NEXT above is a pre-defined macro.
  42.  
  43.         There are many other powerful features of this facility, namely
  44. the use of declarations in the assembly code.  Not only can machine
  45. code be assembled, but any other type of data, including threads,
  46. heads, and data.  Words can be defined using PUBLIC and existing words
  47. can be referenced with EXTRN.  These are all interpreted by the linker
  48. portion of this interface.
  49.  
  50.         Errors during assembly
  51.  
  52.         If the assembler fails to produce an object file, an error
  53. message is displayed, and compilation is aborted.  The programmer must
  54. then examine the error or listing file mentioned in the error message
  55. in order to determine the problem.    The file containing the code to
  56. assemble is usually called  CODE-4TH.ASM, and the file with the errors
  57. is usually named CODE-4TH.ERR or CODE-4TH.LST.
  58.  
  59.         SEGMENT Declarations
  60.  
  61.         The linker supports several reserved segment and class names, for
  62. use in directing code into various segments.  These are: 'CODE', 'THREADS',
  63. 'DATA', 'HEADS', and 'STACKS'.  These reserved names can either be used
  64. as segment names (most common), or as class names.  When used as segment
  65. names any class name then specified, is ignored.
  66.  
  67.         The following segments are declared automatically for the
  68. programmer at the beginning of each assembly.  The programmer need only
  69. switch between them (eg.   HEADS SEGMENT   is sufficient to switch to
  70. heads, without all the other parts of the declaration).
  71.  
  72.         code    segment byte public 'CODE'
  73.         code ends
  74.         threads segment word public 'THREADS'
  75.         threads ends
  76.         data    segment byte public 'DATA'
  77.         data ends
  78.         heads   segment byte public 'HEADS'
  79.         heads ends
  80.         stacks  segment byte public 'STACKS'
  81.         stacks ends
  82.  
  83.         The code segment is the default, if no other is specified,
  84. allowing simple words to assemble with no declarations whatsoever.
  85. There is a statement   CODE SEGMENT  automatically inserted before the
  86. assembler statements, and the statements  CODE ENDS and END after the
  87. end of the assembler word.  The directive:
  88.         ASSUME CS:CODE, DS:CODE, ES:CODE
  89. is also inserted, so no segment overrides will be inserted by the
  90. assembler, unless the programmer explicitly includes them.
  91.  
  92.         Origins
  93.  
  94.         When any segment is declared in an assembler, the origin is assumed
  95. to be 0.  This is fine, when the only code being dealt with is produced by
  96. the assembler; the programmer is in complete control.  Here the
  97. code must be loaded on top of an existing program - L.O.V.E. Forth.
  98. Therefore, the origins have been constructed to follow a slightly
  99. different pattern.
  100.  
  101.         When a reserved name is used for a segment name, the real segment
  102. origin is at 0000 in the L.O.V.E. Forth segment.  The origin (if any) given
  103. by the programmer is incremented by HERE (or CS:HERE, TS:HERE, etc), prior
  104. to the code being loaded in.  This ensures that there are no overwritten
  105. areas of memory.  Alignment attribute is not meaningful for standard
  106. segments, they already start on even byte, word, paragraph and page
  107. boundaries.
  108.  
  109.         Should the programmer desire an origin of 0, in the segment
  110. being declared, a different name (unreserved) should be used.  In this
  111. case, the linker looks to the class name for direction on where to load
  112. the code into memory.  If the class name is not specified, the code is
  113. loaded into the CODE segment.  The alignment type may be specified, if
  114. so desired.  The combine type is ignored.
  115.  
  116.         SEGMENT Examples
  117.  
  118.         The most common declaration is:
  119.         CODE SEGMENT
  120.         which causes the code following it to be placed in the code
  121.         segment.   The origin coming in from the object file (normally
  122.         0 for the first code in that segment) is incremented by the
  123.         dictionary pointer.  Therefore the ORG is forced to be CS:HERE
  124.  
  125.         Another more complex example is:
  126.         MYTHREADS SEGMENT WORD PUBLIC 'THREADS'
  127.         which causes the following code to be loaded into the thread
  128.         segment.  The origin is relative to the start of this declared
  129.         segment.
  130.  
  131.         MYSEG SEGMENT
  132.         Code/data in this segment has it's own origin of 0.
  133.         If grouped however, it has an offset from the start of the
  134.         group  <=64k.  It is placed in ram in one of the standard
  135.         segments (in this case the code segment)
  136.  
  137.         THREADS SEGMENT byte public 'code'
  138.         The segment and class conflict - in this case the class is
  139.         ignored.
  140.  
  141.         GROUP Declaration
  142.  
  143.         The programmer may declare any group, that does not group different
  144. L.O.V.E. Forth segments together (can't because >=64k apart).   A
  145. segment may be part of only one group.
  146.  
  147.         EXTRN declarations
  148.  
  149.         The address or value of existing Forth words may be referenced
  150. in the assembler code, using the EXTRN declaration.    Since words in
  151. L.O.V.E. Forth have several parts, the address of each part may be
  152. obtained, by adding a special prefix to the name desired.  The prefixes
  153. are sorted out by the linker.
  154.  
  155.         Prefix                  Segment         Purpose
  156.                                 Register
  157.         CODE@  (no prefix)      CS      address of machine code
  158.         THREADS@                DS      compilation address
  159.         DATA@                   ES      parameter field address
  160.         HEADS@                  n/a     name field address
  161.         IMMEDIATE@              n/a     special - executes the
  162.                                         following word at link-time to
  163.                                         obtain value
  164.  
  165.         For example:
  166.  
  167.         EXTRN CODE@COUNT:NEAR, DATA@TIB:BYTE, IMMEDIATE@HERE:ABS
  168.  
  169.         MOV BYTE PTR ES:DATA@TIB, 0DH ; install carriage return
  170.         ADD AX,IMMEDIATE@HERE         ; add HERE
  171.         JMP CODE@COUNT                ; exit via a forth word
  172.  
  173.         If the word appears without a prefix or if CODE@ is in front of
  174. the word, then the address of the related machine code is returned.
  175. This is the same as is returned with 'CODE .   Similarly THREADS@
  176. returns the compilation address of the following word.  The most useful
  177. prefix is perhaps DATA@ which returns the parameter field address, the
  178. address returned by a VARIABLE or other word created by CREATE.  HEADS@
  179. returns the name field address.   This is relative to the head segment,
  180. the actual value of which can be obtained from the label HSEG (see
  181. Frame Fixups below).
  182.  
  183.         The word IMMEDIATE@ can execute a word at link-time.  This is
  184. typically a CONSTANT whose value is required, or a VARIABLE whose
  185. address is required in assembly code ( eg. IMMEDIATE@BL ).  It can be
  186. any word that returns a single cell on the stack.  If HERE or the other
  187. dictionary values are referenced, they return the values they had,
  188. prior to linking.
  189.  
  190.         If using MASM the programmer must pay particular attention to
  191. how the external references are declared.  When using the reference as
  192. a memory pointer (eg. BYTE PTR ) the reference must be declared as
  193. :BYTE or :WORD (or other address delaration).  A value used as an
  194. immediate type operand must be declared :ABS .  If mis-declared, MASM
  195. ignores the addressing mode explicitly used in the instruction, in
  196. favour of what is implied in the EXTRN declaration.  A reference can
  197. therefore not be used both as and immediate type operand and a memory
  198. reference.
  199.  
  200.         If using A86, the programmer need not include the EXTRN
  201. directive, as any symbols that are undefined, are automatically
  202. declared external.   And if the EXTRN directive is used any type
  203. declaration (:NEAR, :WORD, :ABS, etc.) may be used, A86 handles all
  204. cases correctly.
  205.  
  206.         Forth Words with Illegal Characters
  207.  
  208.         When words contain characters that are illegal for the
  209. assembler a prefix of %% may be used.  This prefix is dealt with before
  210. assembly begins, and changes the name to one acceptable for the
  211. assembler.  Illegal characters include:  +-*/%^() and many more.
  212. The word prefixed by %% must however be terminated by a space, tab or
  213. end of line.  For example:
  214.         %%-TRAILING         %%+!     %%2DUP
  215.  
  216.         Complete example, a word which exits via */
  217.  
  218.         CODE 550_337_*/ ; ( scale n by this fraction to get m ( n -- m )
  219.            extrn %%*/ :near  ; reference to the word */
  220.            mov ax,550
  221.            push ax
  222.            mov ax,337
  223.            push ax
  224.            jmp %%*/ c;
  225.  
  226.         PUBLIC declarations
  227.  
  228.         Just as it is possible to reference Forth words from within
  229. assember with EXTRN, it is also possible to create new words.   This is
  230. done with the PUBLIC directive.  This can be used to create
  231. multiple entry points in words, or simply to create address references
  232. available in high level code or other code definitions.  The %% prefix
  233. described above, can be used to make names with assembler-illegal
  234. characters.  Example:
  235.  
  236.         CODE QDROP ; ( q -- )
  237.               POP AX  ; yes, there are more efficient ways of coding
  238.               POP AX  ;        this word
  239.         DDROP:POP AX
  240.         DROP: POP AX
  241.               NEXT
  242.  
  243.         PUBLIC DDROP ; ( d -- )
  244.         PUBLIC DROP  ; ( n -- )
  245.         c;
  246.  
  247.         As shown in the table below, PUBLIC declarations work
  248. differently, depending on which segment the label is declared in.  Note
  249. that a reference to the data segment, effectively becomes a VARIABLE .
  250.  
  251.         code segment            A CODE word is created
  252.         threads segment         The PUBLIC address is assumed to be
  253.                                     the compilation address of a word
  254.         other segment           A CONSTANT is created with the value
  255.            names                    of the PUBLIC address
  256.  
  257.         A PUBLIC Caution about FORGET
  258.  
  259.         Words declared PUBLIC are CREATEd at link-time.  Unfortunately
  260. most linkers do not provide PUBLIC declarations in any reasonable
  261. order.  This means that a word deleclared later, may refer to a word
  262. lower in memory.  This conflicts with FORGET which removes everything
  263. above the forgotten word.  When using forget, be sure to forget all of
  264. the words PUBLICly CREATEd within one code word or ASM section.
  265.  
  266.         The Command ASM
  267.  
  268.         ASM is the best way to include a large body of assembly code
  269. into Forth.  ASM simply begins a section of assembly language code.
  270. There is no word CREATEd like CODE , words that require access from
  271. high level Forth or other assembler words, should be declared PUBLIC as
  272. described above.  Many code words can thus be included in one section.
  273. Example:
  274.  
  275.         ASM
  276.         code segment
  277.         BIT:   ; ( access a table of bits ( n -- bit )
  278.                 POP BX
  279.                 ADD BX,BX
  280.                 PUSH es: [BX+bittable]
  281.                 NEXT
  282.         code ends
  283.  
  284.         data segment
  285.         assume cs:data
  286.         bittable: dw 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192
  287.                   dw 16384,32768
  288.         data ends
  289.         PUBLIC BIT
  290.              end c;
  291.  
  292.         Linking OBJect Files
  293.  
  294.         The linker is automatically started after assembling a code 
  295. word with CODE ;CODE or ASM .  It is also possible for the linker to 
  296. operate on existing object files.   The authors may also be delivering 
  297. object file versions of utilities and upgrades in the future.  The 
  298. syntax for this commmand is  LINK"  followed by the path and file name 
  299. of a Microsoft format OBJ file.   For example:
  300.                 LINK" MATRIX.OBJ"
  301.         Would link in the specified file.
  302.  
  303.         Assembler Set-up
  304.  
  305.         Three assemblers are currently supported directly.  A86,
  306. Microsoft MASM version 5, MASM version 6 and Borland TASM.  In order to 
  307. use one of these, the configuration file must be copied to the name 
  308. ASSEMBLY.CFG, for example to use A86 type:
  309.         COPY LOVEA86.CFG  ASSEMBLY.CFG
  310. for MASM,  MASM 6 and TASM, the files are LOVEMASM.CFG LOVEML6.CFG and 
  311. LOVETASM.CFG respectively.  MASM version 6 takes so much memory that 
  312. the extended memory version must be used.  This only works if you omit 
  313. EMM386.
  314.  
  315.         If using another assembler, any of the above files can be
  316. modified according to what the assembler needs.  Read the
  317. instructions in the CFG files (standard ascii).  The following
  318. information must be provided:
  319.         command line
  320.         input, output, listing, error files
  321.         the macro definition for NEXT
  322.         the segment declarations
  323.  
  324.         lines to precede the lines parsed from CODE or ;CODE
  325.         lines to follow the lines from CODE or ;CODE
  326.  
  327.         When the assembly file is created, first the macro
  328. definition, then the segment declarations described above are inserted
  329. into the file, along with the name of the word being assembled (if
  330. applicable).  If assembling the words CODE or ;CODE, the "line to
  331. preceding" those parsed above are inserted, then the lines between
  332. CODE (;CODE) and C;.   The file is terminated with the "lines to
  333. follow" from above.  If the command ASM is used, the lines between ASM
  334. and C; are inserted following the segment declarations, and the file is
  335. terminated.
  336.  
  337.         Improving performance
  338.  
  339.         This method of assembly can be slow on any machine.  The act of
  340. calling another program (assembler) through DOS is time consuming
  341. especially in disk accesses.  There are two ways to speed this up:
  342.  
  343.         1. Use the ASM facility to group CODE words together.  The
  344.            words which would otherwise have been declared separately
  345.            will all be declared at one time, using the PUBLIC 
  346.            declaration.  The assembler is only invoked once per ASM 
  347.            section.
  348.  
  349.         2. Create a small RAM disk to include the temporary files
  350.            listed in ASSEMBLY.CFG (just change the drive and/or
  351.            directory where these are stored).  For most words a size of
  352.            30k should be more than enough.  The assembler itself can
  353.            also be copied to the RAM disk if it is big enough.
  354.  
  355.         Frame Fixups
  356.  
  357.         Frame fixups are not supported.  This means that explicit references
  358. to segments are not allowed.  Keep in mind that on entry to any code word
  359. the segment registers contain the usual segment values.  In addition
  360. there are locations defined in the CS: (CODE segment) that contain the
  361. current addresses of the standard segments.  (These are CONSTANTs).
  362.  
  363. Address         contains segment value          also in register
  364. CSEG            CODE                            CS
  365. TSEG            THREADS                         DS
  366. VSEG            DATA                            ES
  367. SSEG            STACKS                          SS
  368. HSEG            HEADS                           n/a
  369. PSPSEG          DOS program segment prefix      n/a
  370.  
  371.         So access to these values is via the CS register, for example
  372. to load the VS value into DS:
  373.  
  374.                 MOV DS, word ptr CS: IMMEDIATE@VSEG
  375.  
  376.         Why frame fixups are not supported
  377.  
  378.         In order to be used interactively, any frame numbers included
  379. in code would have to be resolved immediately on assembly.  This is not
  380. a problem, the problems occur later.  When an application is SAVEd and
  381. then re-executed at a later time, the location in memory where DOS
  382. loads the program is often different.  Relocation is supported by
  383. DOS; the EXE file header can contain relocation items.  However when
  384. the program is SAVEd, the segment memory images are concatenated and
  385. the result is saved in the EXE file.  It is difficult to determine both
  386. where the fixup locations are, and where they are to point to, since on
  387. re-execution the image is expanded again.  In addition before the image
  388. is to be saved, these references would have to be de-re-located.  Not
  389. completely impossible, but difficult.  Further difficulties ensue if
  390. the program is saved as a final APPLICATION, where the program is both
  391. saved and executed in its concatenated form.
  392.  
  393.         A version of L.O.V.E. Forth in preparation is able to perform
  394. frame fixups (the fixup information is stored as a field in each
  395. dictionary head).  When saving an application with APPLICATION" these
  396. data are transferred to the .EXE header.